<template>
  <div class="native-input-number-wrapper" :class="{ 'is-disabled': disabled }">
    <input
      type="text"
      class="native-input-number"
      :value="modelValue"
      @input="handleInput"
      @change="handleChange"
      :min="min"
      :max="max"
      :step="step"
      :disabled="disabled"
      :placeholder="placeholder"
    />
    <div class="native-input-number-controls" v-if="controlsPosition !== 'none'">
      <div class="native-input-number-increase" @click="increase">
        <svg viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg" width="12" height="12">
          <path fill="currentColor" d="M488.832 344.32l-339.84 356.672a32 32 0 0 0 0 44.16l.384.384a29.44 29.44 0 0 0 42.688 0l320-335.872 319.872 335.872a29.44 29.44 0 0 0 42.688 0l.384-.384a32 32 0 0 0 0-44.16L535.168 344.32a32 32 0 0 0-46.336 0z"></path>
        </svg>
      </div>
      <div class="native-input-number-decrease" @click="decrease">
        <svg viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg" width="12" height="12">
          <path fill="currentColor" d="M831.872 340.864 512 652.672 192.128 340.864a30.592 30.592 0 0 0-42.752 0 29.12 29.12 0 0 0 0 41.6L489.664 714.24a32 32 0 0 0 44.672 0l340.288-331.712a29.12 29.12 0 0 0 0-41.728 30.592 30.592 0 0 0-42.752 0z"></path>
        </svg>
      </div>
    </div>
    <div 
      v-if="clearable && modelValue !== undefined && modelValue !== null && modelValue !== ''" 
      class="native-input-number-clear"
      @click="handleClear"
    >
      <svg viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg" width="12" height="12">
        <path fill="currentColor" d="M512 64a448 448 0 1 1 0 896 448 448 0 0 1 0-896zm0 393.664L407.936 353.6a38.4 38.4 0 1 0-54.336 54.336L457.664 512 353.6 616.064a38.4 38.4 0 1 0 54.336 54.336L512 566.336 616.064 670.4a38.4 38.4 0 1 0 54.336-54.336L566.336 512 670.4 407.936a38.4 38.4 0 1 0-54.336-54.336L512 457.664z"></path>
      </svg>
    </div>
  </div>
</template>

<script setup>
import { defineProps, defineEmits, ref } from 'vue';
import { ElMessage } from 'element-plus';

const props = defineProps({
  modelValue: {
    type: [Number, String],
    default: undefined
  },
  min: {
    type: Number,
    default: -Infinity
  },
  max: {
    type: Number,
    default: Infinity
  },
  step: {
    type: Number,
    default: 1
  },
  disabled: {
    type: Boolean,
    default: false
  },
  placeholder: {
    type: String,
    default: '请输入'
  },
  clearable: {
    type: Boolean,
    default: false
  },
  controlsPosition: {
    type: String,
    default: 'right' // right, none
  },
  integerOnly: {
    type: Boolean,
    default: true
  }
});

const emit = defineEmits(['update:modelValue', 'change']);

// 验证是否为整数
const isInteger = (value) => {
  // 先检查是否为数字
  if (isNaN(value)) return false;
  
  // 检查是否为整数
  return Number.isInteger(parseFloat(value));
};

const handleInput = (event) => {
  let value = event.target.value;
  
  // 处理空值
  if (value === '') {
    emit('update:modelValue', undefined);
    return;
  }
  
  // 验证是否为数字
  if (isNaN(value)) {
    ElMessage.warning('请输入数字');
    event.target.value = props.modelValue !== undefined ? String(props.modelValue) : '';
    return;
  }
  
  // 将输入转换为数字
  const numValue = parseFloat(value);
  
  // 验证整数
  if (props.integerOnly && !isInteger(value)) {
    ElMessage.warning('请输入整数');
    event.target.value = props.modelValue !== undefined ? String(props.modelValue) : '';
    return;
  }
  
  // 检查是否在范围内
  let finalValue = numValue;
  if (numValue < props.min) {
    finalValue = props.min;
  } else if (numValue > props.max) {
    finalValue = props.max;
  }
  
  // 如果值超出范围，更新输入框显示
  if (finalValue !== numValue) {
    event.target.value = String(finalValue);
  }
  
  emit('update:modelValue', finalValue);
};

const handleChange = (event) => {
  const value = event.target.value;
  
  // 处理空值
  if (value === '') {
    emit('update:modelValue', undefined);
    emit('change', undefined);
    return;
  }
  
  // 验证是否为数字
  if (isNaN(value)) {
    ElMessage.warning('请输入数字');
    event.target.value = props.modelValue !== undefined ? String(props.modelValue) : '';
    return;
  }
  
  // 将输入转换为数字
  const numValue = parseFloat(value);
  
  // 验证整数
  if (props.integerOnly && !isInteger(value)) {
    ElMessage.warning('请输入整数');
    event.target.value = props.modelValue !== undefined ? String(props.modelValue) : '';
    emit('update:modelValue', props.modelValue);
    return;
  }
  
  // 确保值在范围内
  let finalValue = numValue;
  if (numValue < props.min) {
    finalValue = props.min;
  } else if (numValue > props.max) {
    finalValue = props.max;
  }
  
  // 如果值超出范围，更新输入框显示
  if (finalValue !== numValue) {
    event.target.value = String(finalValue);
  }
  
  emit('update:modelValue', finalValue);
  emit('change', finalValue);
};

const handleClear = () => {
  emit('update:modelValue', undefined);
  emit('change', undefined);
};

const increase = () => {
  if (props.disabled) return;
  
  let value = props.modelValue === undefined || props.modelValue === null ? 0 : parseFloat(props.modelValue);
  value += props.step;
  
  if (value > props.max) {
    value = props.max;
  }
  
  // 如果要求整数，确保结果是整数
  if (props.integerOnly) {
    value = Math.round(value);
  }
  
  emit('update:modelValue', value);
  emit('change', value);
};

const decrease = () => {
  if (props.disabled) return;
  
  let value = props.modelValue === undefined || props.modelValue === null ? 0 : parseFloat(props.modelValue);
  value -= props.step;
  
  if (value < props.min) {
    value = props.min;
  }
  
  // 如果要求整数，确保结果是整数
  if (props.integerOnly) {
    value = Math.round(value);
  }
  
  emit('update:modelValue', value);
  emit('change', value);
};
</script>

<style scoped>
.native-input-number-wrapper {
  position: relative;
  display: inline-block;
  width: 100%;
  height: 32px;
  box-sizing: border-box;
}

.native-input-number {
  width: 100%;
  height: 32px;
  padding: 0 30px 0 12px;
  border-radius: 4px;
  border: 1px solid #dcdfe6;
  background-color: #fff;
  color: #606266;
  font-size: 14px;
  outline: none;
  transition: border-color 0.2s;
  box-sizing: border-box;
}

.native-input-number:focus {
  border-color: #409eff;
}

.native-input-number:hover {
  border-color: #c0c4cc;
}

.native-input-number-wrapper.is-disabled .native-input-number {
  background-color: #f5f7fa;
  border-color: #e4e7ed;
  color: #c0c4cc;
  cursor: not-allowed;
}

.native-input-number-controls {
  position: absolute;
  height: 100%;
  right: 0;
  top: 0;
  width: 22px;
  display: flex;
  flex-direction: column;
}

.native-input-number-increase,
.native-input-number-decrease {
  display: flex;
  justify-content: center;
  align-items: center;
  height: 50%;
  cursor: pointer;
  color: #c0c4cc;
  transition: color 0.2s;
}

.native-input-number-increase:hover,
.native-input-number-decrease:hover {
  color: #409eff;
}

/* 移除旋转，让增加按钮显示原始向上的箭头 */
.native-input-number-increase {
  transform: none;
}

.native-input-number-wrapper.is-disabled .native-input-number-increase,
.native-input-number-wrapper.is-disabled .native-input-number-decrease {
  cursor: not-allowed;
  color: #e4e7ed;
}

.native-input-number-clear {
  position: absolute;
  top: 0;
  right: 25px;
  height: 100%;
  display: flex;
  align-items: center;
  color: #c0c4cc;
  cursor: pointer;
  opacity: 0;
  transition: opacity 0.2s;
}

.native-input-number-wrapper:hover .native-input-number-clear {
  opacity: 1;
}

.native-input-number-clear:hover {
  color: #909399;
}

/* 隐藏浏览器默认的上下箭头 */
.native-input-number::-webkit-inner-spin-button,
.native-input-number::-webkit-outer-spin-button {
  -webkit-appearance: none;
  margin: 0;
}

.native-input-number {
  -moz-appearance: textfield;
}

/* CEF浏览器特殊样式 */
body.cef-browser .native-input-number {
  height: 32px;
  line-height: 32px;
  max-height: 32px;
}
</style> 